#ifndef __M_EPOLL_H__
#define __M_EPOLL_H__

#include <iostream>
#include <unistd.h>
#include <sys/epoll.h>

// 对原生epoll进行封装，epoll_create epoll_ctl epoll_del
// 但是

class Epoller {

    public:
        Epoller() :_epfd(-1) {

            _epfd = epoll_create(128);
            if(_epfd < 0) {
                std::cerr << "epoll create error!" << std::endl;
                exit(-1);
            }
        }

        void ModEventHelper(int sockfd, uint32_t events, int oper) {
            struct epoll_event ev;
            ev.events = events;
            ev.data.fd = sockfd;
            if(epoll_ctl(_epfd, oper, sockfd, &ev) < 0) {
                std::cerr << "epoll ctl error!" << std::endl;
                return;
            }
        }

        void AddEvent(int sockfd, uint32_t events) {
            return ModEventHelper(sockfd, events, EPOLL_CTL_ADD);
        }

        void ModEvent(int sockfd, uint32_t newevents) {
            return ModEventHelper(sockfd, newevents, EPOLL_CTL_MOD);
        }

        void delEvent(int sockfd) {
            if(epoll_ctl(_epfd, EPOLL_CTL_DEL, sockfd, nullptr) < 0) {
                std::cerr << "epoll del error!" << std::endl;
                return;
            }
        }

        int WaitEvent(struct epoll_event revs[], int max_num, int timeout) {
            int n = epoll_wait(_epfd, revs, max_num, timeout);
            if(n < 0) {
                std::cerr << "epoll wait error!";
            }
            else if(n == 0) {
                std::cerr << "epoll wait timeout" << std::endl;
            }
            
            return n;
        }

        ~Epoller() {
            if(_epfd >= 0) {
                close(_epfd);
            }

        }

    private:
        int _epfd;
};




#endif